package com.starblink.android.basic.base

//import com.starblink.android.basic.BR
import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
import android.os.Bundle
import android.os.Handler
import androidx.multidex.MultiDex
import com.adjust.sdk.Adjust
import com.alibaba.android.arouter.launcher.ARouter
import com.blankj.utilcode.util.Utils
import com.drake.statelayout.StateConfig
import com.starblink.android.basic.BuildConfig
import com.starblink.android.basic.R
import com.starblink.android.basic.brv.PageRefreshLayout
import com.starblink.android.basic.core.BaseLibCore
import com.starblink.android.basic.guide.SkNoviceManage
import com.starblink.android.basic.network.base.BaseApiConfig
import com.starblink.android.basic.receiver.ConnectivityReceiver
import com.starblink.android.basic.widget.refresher.SKRefresher
import com.starblink.basic.autosize.AutoSize
import com.starblink.basic.autosize.AutoSizeConfig
import com.starblink.basic.autosize.onAdaptListener
import com.starblink.basic.autosize.utils.AutoSizeLog
import com.starblink.basic.autosize.utils.ScreenUtils
import com.starblink.basic.log.SKLogger
import com.starblink.basic.storage.SkStorage
import com.starblink.basic.util.ActivityStackManage
import com.starblink.basic.util.NetWorkUtil
import java.util.Locale
import java.util.concurrent.Executors

abstract class BaseApplication : Application() {

    //全局的静态Gson对象
    companion object {
        //        val mGson = Gson()
        lateinit var networkType: NetWorkUtil.NetworkType   //此变量会在网络监听中被动态赋值
        var CURRENT_FLAVOR = BaseApiConfig.DEFAULT_FLAVOR

        //检查当前是否有网络
        fun checkHasNet(): Boolean {
            return networkType != NetWorkUtil.NetworkType.NETWORK_NO && networkType != NetWorkUtil.NetworkType.NETWORK_UNKNOWN
        }

        const val YY_LOG_CLOSE = false

    }

    abstract fun onInit(): Unit

    override fun onCreate() {
        super.onCreate()

        Utils.init(this) // 避免工具类自己反射获取
        SKLogger.initLog(this)
        SkStorage.initStorage(this)
        if (BuildConfig.DEBUG) {
            ARouter.openLog()
            ARouter.openDebug()
        }
        //初始化埋点
        ARouter.init(this)
        SKRefresher.initRefreshStyle()
        onInitFirst()
        onInit()
        SKLogger.d(
            "BaseApplication",
            "-->> onCreate: ${Resources.getSystem().displayMetrics}, -->> densityDpi: ${Resources.getSystem().displayMetrics.densityDpi}"
        )
    }


    fun registerAdjustCallBack() {
        registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
                ActivityStackManage.setTopActivity(activity)
            }

            override fun onActivityStarted(activity: Activity) {
//                ActivityStackManage.setTopActivity(activity)
            }

            override fun onActivityResumed(activity: Activity) {
                ActivityStackManage.setTopActivity(activity)
                Adjust.onResume()
            }

            override fun onActivityPaused(activity: Activity) {
//                ActivityStackManage.setTopActivity(activity)
                Adjust.onPause()
            }

            override fun onActivityStopped(activity: Activity) {
//                ActivityStackManage.setTopActivity(activity)
            }

            override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
            }

            override fun onActivityDestroyed(activity: Activity) {
//                ActivityStackManage.setTopActivity(activity)
            }
        })

    }


    override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(base)
        MultiDex.install(this)
    }


    override fun onTerminate() {
        super.onTerminate()
        ConnectivityReceiver.unregisterReceiver(this)
    }


    private fun onInitFirst() {
        //全局的 CommUtil的初始化
        BaseLibCore.init(this, Handler(), android.os.Process.myTid())

        initAutoSize()
        initBRV()
        //初始化引导弹窗
        SkNoviceManage.initVoiceGuide()

    }

    //初始化默认替换布局
    private fun initBRV() {
//        // 初始化BindingAdapter的默认绑定ID
//        BRV.modelId = BR.m
        // 禁止错误缺省页启用下拉刷新
        PageRefreshLayout.refreshEnableWhenError = false

        /**
         *  推荐在Application中进行全局配置缺省页, 当然同样每个页面可以单独指定缺省页.
         *  具体查看 https://github.com/liangjingkanji/StateLayout
         */
        StateConfig.apply {
            emptyLayout = com.starblink.basic.style.R.layout.base_layout_empty
            errorLayout = com.starblink.basic.style.R.layout.base_layout_error
            loadingLayout = com.starblink.basic.style.R.layout.base_layout_loading

            setRetryIds(R.id.icon, com.starblink.basic.style.R.id.msg)

            onLoading {
                // 此生命周期可以拿到LoadingLayout创建的视图对象, 可以进行动画设置或点击事件.
            }
        }

    }


    fun initNetWorkReceiver(flavor: String) {
        CURRENT_FLAVOR = flavor
        BaseApiConfig.onInit(this@BaseApplication.applicationContext, flavor)

        //获取到全局的网络状态
        networkType = NetWorkUtil.getNetworkType(this@BaseApplication.applicationContext)
        //网络监听
        ConnectivityReceiver.registerReceiver(this)
    }

    //屏幕适配
    private fun initAutoSize() {

        //当 App 中出现多进程, 并且您需要适配所有的进程, 就需要在 App 初始化时调用 initCompatMultiProcess()
        AutoSize.initCompatMultiProcess(this)
        //如果在某些特殊情况下出现 InitProvider 未能正常实例化, 导致 AndroidAutoSize 未能完成初始化
        //可以主动调用 AutoSize.checkAndInit(this) 方法, 完成 AndroidAutoSize 的初始化后即可正常使用
//        AutoSize.checkAndInit(this);

//        如何控制 AndroidAutoSize 的初始化，让 AndroidAutoSize 在某些设备上不自动启动？https://github.com/JessYanCoding/AndroidAutoSize/issues/249

        /**
         * 以下是 AndroidAutoSize 可以自定义的参数, {@link AutoSizeConfig} 的每个方法的注释都写的很详细
         * 使用前请一定记得跳进源码，查看方法的注释, 下面的注释只是简单描述!!!
         */

        //如果在某些特殊情况下出现 InitProvider 未能正常实例化, 导致 AndroidAutoSize 未能完成初始化
        //可以主动调用 AutoSize.checkAndInit(this) 方法, 完成 AndroidAutoSize 的初始化后即可正常使用
//        AutoSize.checkAndInit(this);

//        如何控制 AndroidAutoSize 的初始化，让 AndroidAutoSize 在某些设备上不自动启动？https://github.com/JessYanCoding/AndroidAutoSize/issues/249
        /**
         * 以下是 AndroidAutoSize 可以自定义的参数, [AutoSizeConfig] 的每个方法的注释都写的很详细
         * 使用前请一定记得跳进源码，查看方法的注释, 下面的注释只是简单描述!!!
         */
        AutoSizeConfig.getInstance() //是否让框架支持自定义 Fragment 的适配参数, 由于这个需求是比较少见的, 所以须要使用者手动开启
            //如果没有这个需求建议不开启
//            .setCustomFragment(true)
             //设置应用的字体不随系统的字体大小而改变
            .setExcludeFontScale(true)
            .onAdaptListener = object : onAdaptListener {
            override fun onAdaptBefore(target: Any, activity: Activity?) {
                //使用以下代码, 可以解决横竖屏切换时的屏幕适配问题
                //使用以下代码, 可支持 Android 的分屏或缩放模式, 但前提是在分屏或缩放模式下当用户改变您 App 的窗口大小时
                //系统会重绘当前的页面, 经测试在某些机型, 某些情况下系统不会重绘当前页面, ScreenUtils.getScreenSize(activity) 的参数一定要不要传 Application!!!
                AutoSizeConfig.getInstance().screenWidth = ScreenUtils.getScreenSize(activity)[0];
                //                        AutoSizeConfig.getInstance().setScreenHeight(ScreenUtils.getScreenSize(activity)[1]);
                AutoSizeLog.d(
                    String.format(
                        Locale.ENGLISH,
                        "%s onAdaptBefore!",
                        target.javaClass.name
                    )
                )
            }

            override fun onAdaptAfter(target: Any, activity: Activity?) {
                AutoSizeLog.d(
                    String.format(
                        Locale.ENGLISH,
                        "%s onAdaptAfter!",
                        target.javaClass.name
                    )
                )
            }
        } //是否打印 AutoSize 的内部日志, 默认为 true, 如果您不想 AutoSize 打印日志, 则请设置为 false
        //                .setLog(false)
        //是否使用设备的实际尺寸做适配, 默认为 false, 如果设置为 false, 在以屏幕高度为基准进行适配时
        //AutoSize 会将屏幕总高度减去状态栏高度来做适配
        //设置为 true 则使用设备的实际屏幕高度, 不会减去状态栏高度
        //在全面屏或刘海屏幕设备中, 获取到的屏幕高度可能不包含状态栏高度, 所以在全面屏设备中不需要减去状态栏高度，所以可以 setUseDeviceSize(true)
        //                .setUseDeviceSize(true)
        //是否全局按照宽度进行等比例适配, 默认为 true, 如果设置为 false, AutoSize 会全局按照高度进行适配
        //                .setBaseOnWidth(false)
        //设置屏幕适配逻辑策略类, 一般不用设置, 使用框架默认的就好
        //                .setAutoAdaptStrategy(new AutoAdaptStrategy())

    }

}